home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / lib / init_color.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  15KB  |  456 lines

  1. /*************************************************************************
  2.  *                                                                       *
  3.  *  Copyright (c) 1992, 1993 Ronald Joe Record                           *
  4.  *                                                                       *
  5.  *  All rights reserved. No part of this program or publication may be   *
  6.  *  reproduced, transmitted, transcribed, stored in a retrieval system,  *
  7.  *  or translated into any language or computer language, in any form or *
  8.  *  by any means, electronic, mechanical, magnetic, optical, chemical,   *
  9.  *  biological, or otherwise, without the prior written permission of:   *
  10.  *                                                                       *
  11.  *      Ronald Joe Record (408) 458-3718                                 *
  12.  *      212 Owen St., Santa Cruz, California 95062 USA                   *
  13.  *                                                                       *
  14.  *************************************************************************/
  15.  
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <X11/Xlib.h>
  21. #include "libXrr.h"
  22.  
  23. int _numdivs = 2;
  24. static char mapfile[128];
  25.  
  26. void
  27. set_mapfile_name(display, res, prog)
  28. Display *display;
  29. char *res;
  30. char *prog;
  31. {
  32.     char *tmpmapfile;
  33.  
  34.     if ((tmpmapfile = XGetDefault(display, res, "Mapfile")) == NULL) {
  35.            if (strcpy(mapfile, getenv("HOME")) == NULL)
  36.             fprintf(stderr, "Warning: strcpy of HOME failed\n");
  37.            if (strcat(mapfile, "/.") == NULL)
  38.             fprintf(stderr, "Warning: strcat of /. failed\n");
  39.            if (strcat(mapfile, prog) == NULL)
  40.             fprintf(stderr, "Warning: strcat of prog failed\n");
  41.            if (strcat(mapfile, "map") == NULL)
  42.             fprintf(stderr, "Warning: strcat of map failed\n");
  43.     }
  44.     else
  45.         if (strcpy(mapfile, tmpmapfile) == NULL)
  46.             fprintf(stderr, "Warning: strcpy of tmpmapfile failed\n");
  47. }
  48.  
  49. void
  50. init_color(display, win, cmap, Colors, s_col, min, n_cols, wheel, prog, res, n)
  51. Display *display;
  52. Window win;
  53. Colormap cmap;
  54. XColor *Colors;
  55. int s_col, min, n_cols, wheel, n;
  56. char *prog;
  57. char *res;
  58. {
  59.     static short i, j, first_time=1;
  60.     static int colgap, leg, step, numfree;
  61.     static double d;
  62.     Colormap def_cmap;
  63.     int hls[3], rgb[3];
  64.     FILE *map;
  65.     char buf[255];
  66.     int a, b, c, c_end;
  67.     extern void hls2rgb();
  68.     extern long lrand48();
  69.  
  70.     def_cmap = DefaultColormap(display, DefaultScreen(display));
  71.     for (i=0; i<n_cols; i++) {
  72.         Colors[i].pixel = i;
  73.         Colors[i].flags = DoRed|DoGreen|DoBlue;
  74.     }
  75.     XQueryColors(display, def_cmap, Colors, n_cols);
  76.     colgap = RGB_MAX / n_cols;
  77.     hls[0] = 50;    /* Hue in low range */
  78.     hls[2] = 1000;  /* Fully saturated */
  79.     for (i=s_col; i<min; i++) {
  80.         hls[1] = 1000L * (i-s_col) / (min - s_col);
  81.         hls2rgb(hls, rgb);
  82.         Colors[i].red = rgb[0];
  83.         Colors[i].green = rgb[1];
  84.         Colors[i].blue = rgb[2];
  85.     }
  86.     numfree = n_cols - min;
  87.     switch (wheel) {
  88.     case -2: /* black & white palette */
  89.         hls[1] = 1000;    /* Fully Light */
  90.         hls[2] = 1000;    /* Fully saturated */
  91.         for (i=s_col; i<((n_cols-s_col)/2)+s_col; i++) {
  92.             hls[0] = 3000L;
  93.             hls2rgb(hls, rgb);
  94.             Colors[i].red = rgb[0];
  95.             Colors[i].green = rgb[1];
  96.             Colors[i].blue = rgb[2];
  97.         }
  98.         hls[1] = 0;    /* Fully Dark */
  99.         hls[2] = 0;
  100.         for (i=((n_cols-s_col)/2)+s_col; i<n_cols; i++) {
  101.             hls[0] = 0;
  102.             hls2rgb(hls, rgb);
  103.             Colors[i].red = rgb[0];
  104.             Colors[i].green = rgb[1];
  105.             Colors[i].blue = rgb[2];
  106.         }
  107.         break;
  108.     case -1:    /* white palette */
  109.         hls[1] = 1000;    /* Fully Light */
  110.         hls[2] = 1000;    /* Fully saturated */
  111.         for (i=s_col; i<n_cols; i++) {
  112.             hls[0] = 3000L;
  113.             hls2rgb(hls, rgb);
  114.             Colors[i].red = rgb[0];
  115.             Colors[i].green = rgb[1];
  116.             Colors[i].blue = rgb[2];
  117.         }
  118.         break;
  119.     case 0: /* read in cmap from $HOME/.<progname>map */
  120.         if (first_time) {
  121.             set_mapfile_name(display, res, prog);
  122.             first_time = 0;
  123.         }
  124.         i = s_col;
  125.         if ((map = fopen(mapfile, "r")) != NULL) {
  126.             while(!feof(map) && i <n_cols) {
  127.                 fgets(buf,sizeof buf,map);
  128.                 if(sscanf(buf,"%d %d %d",&a,&b,&c) == 3) {
  129.                     Colors[i].red = a * 256;
  130.                     Colors[i].green = b * 256;
  131.                     Colors[i].blue = c * 256;
  132.                     i++;
  133.                     if (i >= n_cols)
  134.                         break;
  135.                 }
  136.             }
  137.             c_end = i;
  138.             while (i<n_cols) {
  139.                 Colors[i].red = Colors[i - c_end].red;
  140.                 Colors[i].green = Colors[i - c_end].green;
  141.                 Colors[i].blue = Colors[i - c_end].blue;
  142.                 i++;
  143.             }
  144.         }
  145.         fclose(map);
  146.         break;
  147.     case 1: /* gray-scale palette */
  148.         for (i=s_col; i<n_cols; i++) {
  149.             Colors[i].red = ((i-s_col)*60000/(n_cols-s_col)) + 5535;
  150.             Colors[i].green = ((i-s_col)*60000/(n_cols-s_col)) + 5535;
  151.             Colors[i].blue = ((i-s_col)*60000/(n_cols-s_col)) + 5535;
  152.         }
  153.         break;
  154.     case 2:
  155.         hls[0] = 800;    /* Hue in mid range */
  156.         hls[2] = 1000;    /* Fully saturated */
  157.         for (i=s_col; i<min; i++) {
  158.             hls[1]=1000L*(i-s_col) / (min - s_col);
  159.             hls2rgb(hls, rgb);
  160.             Colors[i].red = rgb[0];
  161.             Colors[i].green = rgb[1];
  162.             Colors[i].blue = rgb[2];
  163.         }
  164.         for (i=min; i<min+(numfree/2); i++) {
  165.             Colors[i].blue = RGB_MAX;
  166.             Colors[i].green = 0;
  167.             Colors[i].red=(i*2*RGB_MAX/n_cols);
  168.         }
  169.         for (i=min+(numfree/2); i<n_cols; i++) {
  170.             Colors[i].blue = RGB_MAX;
  171.             Colors[i].green = 0;
  172.             Colors[i].red=((n_cols - i)*2*RGB_MAX/n_cols);
  173.         }
  174.         break;
  175.     case 3:
  176.         hls[0] = 800;    /* Hue in mid range */
  177.         hls[2] = 1000;    /* Fully saturated */
  178.         for (i=s_col; i<min; i++) {
  179.             hls[1]=1000L*(i-s_col) / (min - s_col);
  180.             hls2rgb(hls, rgb);
  181.             Colors[i].red = rgb[0];
  182.             Colors[i].green = rgb[1];
  183.             Colors[i].blue = rgb[2];
  184.         }
  185.         colgap = 4*RGB_MAX/n_cols;
  186.         for (i=min; i<min+(numfree/4); i++) {
  187.             Colors[i].blue = RGB_MAX;
  188.             Colors[i].green = 0;
  189.             Colors[i].red=(i*colgap);
  190.         }
  191.         for (i=min+(numfree/4);i<min+(numfree/2);i++) {
  192.             Colors[i].red = RGB_MAX;
  193.             Colors[i].green = 0;
  194.             Colors[i].blue=(min+(numfree/2) - i) * colgap;
  195.         }
  196.         for(i=min+(numfree/2);i<min+(0.75*numfree);i++){
  197.             Colors[i].red = RGB_MAX;
  198.             Colors[i].blue=(i * colgap);
  199.             Colors[i].green = 0;
  200.         }
  201.         for (i=min+(0.75*numfree); i<n_cols; i++) {
  202.             Colors[i].blue = RGB_MAX;
  203.             Colors[i].green = 0;
  204.             Colors[i].red=(n_cols-i)*colgap;
  205.         }
  206.         break;
  207.     case 4:
  208.         hls[0] = 800;    /* Hue in mid range */
  209.         hls[2] = 1000;    /* Fully saturated */
  210.         for (i=s_col; i<min; i++) {
  211.             hls[1] = 1000L * (i-s_col) / (min - s_col);
  212.             hls2rgb(hls, rgb);
  213.             Colors[i].red = rgb[0];
  214.             Colors[i].green = rgb[1];
  215.             Colors[i].blue = rgb[2];
  216.         }
  217.         colgap = wheel * RGB_MAX / n_cols;
  218.         for (i=min; i<(n_cols/wheel); i++) {
  219.             Colors[i].blue = RGB_MAX;
  220.             Colors[i].green = 0;
  221.             Colors[i].red=(i*colgap);
  222.         }
  223.         for (i=(n_cols/wheel); i<(2*n_cols/wheel); i++) {
  224.             Colors[i].red = RGB_MAX;
  225.             Colors[i].green = 0;
  226.             Colors[i].blue=((2*n_cols/wheel) - i) * colgap;
  227.         }
  228.         for (i=(2*n_cols/wheel); i<n_cols; i++) {
  229.             Colors[i].red = RGB_MAX;
  230.             Colors[i].green=(i - (2*n_cols/wheel)) * colgap;
  231.             Colors[i].blue = 0;
  232.         }
  233.         break;
  234.     case 5:
  235.         hls[1] = 700;    /* Lightness in midrange */
  236.         hls[2] = 1000;    /* Fully saturated */
  237.         for (i=min; i<n_cols; i++) {
  238.             hls[0] = 3600L * i / n_cols;
  239.             hls2rgb(hls, rgb);
  240.             Colors[i].red = rgb[0];
  241.             Colors[i].green = rgb[1];
  242.             Colors[i].blue = rgb[2];
  243.         }
  244.         for (i=min; i<n_cols; i+=((n_cols-min)/10)) {
  245.             hls[0] = 3600L * i / n_cols;
  246.             hls2rgb(hls, rgb);
  247.             Colors[i].red = rgb[0] / 2;
  248.             Colors[i].green = rgb[1] / 2;
  249.             Colors[i].blue = rgb[2] / 2;
  250.         }
  251.         break;
  252.     case 6:
  253.         hls[0] = 800;    /* Hue in mid range */
  254.         hls[2] = 1000;    /* Fully saturated */
  255.         for (i=s_col; i<min; i++) {
  256.             hls[1] = 1000L * (i-s_col) / (min - s_col);
  257.             hls2rgb(hls, rgb);
  258.             Colors[i].red = rgb[0];
  259.             Colors[i].green = rgb[1];
  260.             Colors[i].blue = rgb[2];
  261.         }
  262.         step = numfree / 3;
  263.         leg = step+min;
  264.         for (i = min; i < leg; ++i) {
  265.             Colors[i].pixel = i;
  266.             Colors[i].red = fabs(65535 - (double)i / step * 65535.0);
  267.             Colors[i].blue = (double)i / step * 65535.0;
  268.             Colors[i].green = 0;
  269.             Colors[i].flags = DoRed | DoGreen | DoBlue;
  270.         }
  271.         for (j = 0, i = leg, leg += step; i < leg; ++i, ++j) {
  272.             Colors[i].pixel = i;
  273.             Colors[i].red = (double)j / step * 65535.0;
  274.             Colors[i].blue = 65535;
  275.             Colors[i].green = Colors[i].red;
  276.             Colors[i].flags = DoRed | DoGreen | DoBlue;
  277.         }
  278.         for (j = 0, i = leg, leg += step; i < leg; ++i, ++j) {
  279.             Colors[i].pixel = i;
  280.             Colors[i].red = 65535;
  281.             Colors[i].blue = fabs(65535 - (double)j / step * 65535.0);
  282.             Colors[i].green = Colors[i].blue;
  283.             Colors[i].flags = DoRed | DoGreen | DoBlue;
  284.         }
  285.         break;
  286.     case 7: /* random palette */
  287.         hls[1] = 500;    /* Lightness in midrange */
  288.         hls[2] = 1000;    /* Fully saturated */
  289.         for (i=min; i<n_cols; i++) {
  290.             hls[0] = 3600L * (lrand48() % n_cols) / n_cols;
  291.             hls2rgb(hls, rgb);
  292.             Colors[i].red = rgb[0];
  293.             Colors[i].green = rgb[1];
  294.             Colors[i].blue = rgb[2];
  295.         }
  296.         break;
  297.     /* wheel=8 indicates the default color map which is already queried */
  298.     case 9: /* red, green, blue for 3 basins */
  299.         hls[0] = 60;   /* hue at low end */
  300.         hls[2] = 1000;    /* Fully saturated */
  301.         for (i=s_col; i<((n_cols-s_col)/3)+s_col; i++) {
  302.             hls[1] = 800L * i / (((n_cols-s_col)/3)+s_col);
  303.             hls2rgb(hls, rgb);
  304.             Colors[i].red = rgb[0];
  305.             Colors[i].green = rgb[1];
  306.             Colors[i].blue = rgb[2];
  307.         }
  308.         hls[0] = 800;   /* hue in middle */
  309.         for (i=((n_cols-s_col)/3)+s_col;i<(2*(n_cols-s_col)/3)+s_col;i++) {
  310.             hls[1] = 800L * i / ((2*(n_cols-s_col)/3)+s_col);
  311.             hls2rgb(hls, rgb);
  312.             Colors[i].red = rgb[0];
  313.             Colors[i].green = rgb[1];
  314.             Colors[i].blue = rgb[2];
  315.         }
  316.         hls[0] = 1600;   /* hue in upper range */
  317.         for (i=(2*(n_cols-s_col)/3)+s_col; i<n_cols; i++) {
  318.             hls[1] = 800L * i / n_cols;
  319.             hls2rgb(hls, rgb);
  320.             Colors[i].red = rgb[0];
  321.             Colors[i].green = rgb[1];
  322.             Colors[i].blue = rgb[2];
  323.         }
  324.         break;
  325.     case 10: /* palette of several rainbows */
  326.         hls[1] = 500;    /* Lightness in midrange */
  327.         hls[2] = 1000;    /* Fully saturated */
  328.         for (i=s_col; i<n_cols; i++) {
  329.             hls[0] = 3000L*((i-s_col)%((n_cols-s_col)/_numdivs)) 
  330.                     / ((n_cols-s_col)/_numdivs);
  331.             hls2rgb(hls, rgb);
  332.             Colors[i].red = rgb[0];
  333.             Colors[i].green = rgb[1];
  334.             Colors[i].blue = rgb[2];
  335.         }
  336.         break;
  337.     case 11:
  338.         colgap = 2*RGB_MAX/(n_cols - ((n_cols + min)/2));
  339.         for (i=min; i<min+(numfree/2); i++) {
  340.             Colors[i].blue = 0;
  341.             Colors[i].green=((i+((n_cols + min)/2))*colgap);
  342.             Colors[i].red=((i+((n_cols + min)/2))*colgap);
  343.         }
  344.         for (i=min+(numfree/2); i<n_cols; i++) {
  345.             Colors[i].blue = 0;
  346.             Colors[i].green=(((n_cols-i)+((n_cols + min)/2))*colgap);
  347.             Colors[i].red=(((n_cols-i)+((n_cols + min)/2))*colgap);
  348.         }
  349.         break;
  350.     case 12: /* green colormap */
  351.         hls[0] = 1200;    /* Green Hue */
  352.         hls[2] = 1000;    /* Fully saturated */
  353.         for (i=s_col; i<n_cols; i++) {
  354.             hls[1] = (800L * (n_cols - i) / (n_cols - s_col)) + 100L;
  355.             hls2rgb(hls, rgb);
  356.             Colors[i].red = rgb[0];
  357.             Colors[i].green = rgb[1];
  358.             Colors[i].blue = rgb[2];
  359.         }
  360.         break;
  361.     case 13: /* green "tent" shaped colormap */
  362.         colgap = 2*RGB_MAX/(n_cols - ((n_cols + min)/2));
  363.         for (i=s_col; i<s_col+((n_cols - s_col)/2); i++) {
  364.             Colors[i].blue = 0;
  365.             Colors[i].green=((i+((n_cols + min)/2))*colgap);
  366.             Colors[i].red=((i+((n_cols + min)/2))*colgap);
  367.         }
  368.         for (i=s_col+((n_cols - s_col)/2); i<n_cols; i++) {
  369.             Colors[i].blue = 0;
  370.             Colors[i].green=(((n_cols-i)+((n_cols + min)/2))*colgap);
  371.             Colors[i].red=(((n_cols-i)+((n_cols + min)/2))*colgap);
  372.         }
  373.         break;
  374.     case 14: /* red, green, blue for n basins */
  375.         hls[2] = 1000L;
  376.         if (n) {
  377.             d = (double)(n_cols - s_col)/(double)n;
  378.             for (j=0; j<n; j++) {
  379.                 hls[0] = (j*2500L/n)+250L; /* hue */
  380.                 for (i=s_col+(j*d); i<((j+1)*d)+s_col; i++) {
  381.                     if (i >= n_cols)
  382.                         break;
  383.                     hls[1] = 250L + (500L * (double)(i-s_col-(j*d)) / d);
  384.                     hls2rgb(hls, rgb);
  385.                     Colors[i].red = rgb[0];
  386.                     Colors[i].green = rgb[1];
  387.                     Colors[i].blue = rgb[2];
  388.                 }
  389.             }
  390.         }
  391.         else {
  392.             hls[0] = 0L; /* hue */
  393.             for (i=s_col; i<n_cols; i++) {
  394.                 hls[1] = 100L + (800L * (double)(i-s_col) / (n_cols - s_col));
  395.                 hls2rgb(hls, rgb);
  396.                 Colors[i].red = rgb[0];
  397.                 Colors[i].green = rgb[1];
  398.                 Colors[i].blue = rgb[2];
  399.             }
  400.         }
  401.         break;
  402.     case 15: /* reverse rainbow palette */
  403.         hls[1] = 500;    /* Lightness in midrange */
  404.         hls[2] = 1000;    /* Fully saturated */
  405.         for (i=s_col; i<n_cols; i++) {
  406.             hls[0] = 3000L * (i - s_col) / (n_cols - s_col);
  407.             hls2rgb(hls, rgb);
  408.             Colors[i].red = rgb[0];
  409.             Colors[i].green = rgb[1];
  410.             Colors[i].blue = rgb[2];
  411.         }
  412.         break;
  413.     case 16: /* rainbow palette */
  414.         hls[1] = 500;    /* Lightness in midrange */
  415.         hls[2] = 1000;    /* Fully saturated */
  416.         for (i=s_col; i<n_cols; i++) {
  417.             hls[0] = 3000L * (i - s_col) / (n_cols - s_col);
  418.             hls2rgb(hls, rgb);
  419.             Colors[i].red = rgb[0];
  420.             Colors[i].green = rgb[1];
  421.             Colors[i].blue = rgb[2];
  422.         }
  423.         break;
  424.     }
  425.     XStoreColors(display, cmap, Colors, n_cols);
  426.     /* install new color map */
  427.     XSetWindowColormap(display, win, cmap);
  428. }
  429.  
  430. void
  431. write_cmap(display, cmap, Colors, n_cols, prog, res)
  432. Display *display;
  433. Colormap cmap;
  434. XColor *Colors;
  435. int n_cols;
  436. char *prog;
  437. char *res;
  438. {
  439.     FILE *outfile;
  440.     static int i;
  441.  
  442.     set_mapfile_name(display, res, prog);
  443.     outfile = fopen(mapfile,"w");
  444.     if (!outfile) {
  445.         perror(mapfile);
  446.         return;
  447.     }
  448.     else {
  449.         XQueryColors(display, cmap, Colors, n_cols);
  450.         for (i=0; i<n_cols; i++)
  451.             fprintf(outfile,"%d %d %d\n",
  452.                 Colors[i].red/256, Colors[i].green/256, Colors[i].blue/256);
  453.     }
  454.     fclose(outfile);
  455. }
  456.